package com.xmtlxx.web.controller.oms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xmtlxx.common.core.domain.PageQuery;
import com.xmtlxx.common.core.domain.entity.SysDept;
import com.xmtlxx.common.core.domain.model.LoginUser;
import com.xmtlxx.common.core.page.TableDataInfo;
import com.xmtlxx.common.enums.PropertyLogNode;
import com.xmtlxx.common.enums.PropertyLogType;
import com.xmtlxx.common.exception.ServiceException;
import com.xmtlxx.common.helper.LoginHelper;
import com.xmtlxx.common.tengbo.PushDatasUtil;
import com.xmtlxx.common.tengbo.vo.PropertyLogModelsVo;
import com.xmtlxx.common.tengbo.vo.StagingDatasVo;
import com.xmtlxx.common.utils.DateUtils;
import com.xmtlxx.common.utils.JsonUtils;
import com.xmtlxx.common.utils.StringUtils;
import com.xmtlxx.common.utils.push.domain.PushContent;
import com.xmtlxx.common.utils.redis.RedisUtils;
import com.xmtlxx.oms.domain.Classify;
import com.xmtlxx.oms.domain.Property;
import com.xmtlxx.oms.domain.PropertyLog;
import com.xmtlxx.oms.domain.Staging;
import com.xmtlxx.oms.domain.bo.PropertyLogBo;
import com.xmtlxx.oms.domain.bo.StagingBo;
import com.xmtlxx.oms.domain.vo.StagingInfoVo;
import com.xmtlxx.oms.domain.vo.StagingVo;
import com.xmtlxx.oms.mapper.ClassifyMapper;
import com.xmtlxx.oms.mapper.PropertyLogMapper;
import com.xmtlxx.oms.mapper.PropertyMapper;
import com.xmtlxx.oms.mapper.StagingMapper;
import com.xmtlxx.system.domain.SysOss;
import com.xmtlxx.system.domain.bo.SysOssBo;
import com.xmtlxx.system.mapper.SysDeptMapper;
import com.xmtlxx.system.mapper.SysOssMapper;
import com.xmtlxx.system.mapper.SysUserMapper;
import com.xmtlxx.system.service.ISysNoticeService;
import com.xmtlxx.web.controller.center.FinanceController;
import com.xmtlxx.web.controller.center.service.ICommonService;
import com.xmtlxx.web.controller.oms.service.IStagingService;
import com.xmtlxx.wms.domain.*;
import com.xmtlxx.wms.domain.vo.InventoryVo;
import com.xmtlxx.wms.mapper.ExWarehouseDtlMapper;
import com.xmtlxx.wms.mapper.ExWarehouseMapper;
import com.xmtlxx.wms.mapper.InventoryLogMapper;
import com.xmtlxx.wms.mapper.StoreMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 暂存登记Service业务层处理
 *
 * @author xmtlxx
 * @date 2022-11-20
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class StagingServiceImpl implements IStagingService {

    private final FinanceController financeController;

    private final StagingMapper baseMapper;

    private final PropertyMapper propertyMapper;

    private final PropertyLogMapper propertyLogMapper;

    private final InventoryLogMapper inventoryLogMapper;

    private final StoreMapper storeMapper;

    private final SysOssMapper sysOssMapper;

    private final ExWarehouseMapper exWarehouseMapper;

    private final ExWarehouseDtlMapper exWarehouseDtlMapper;

    private final SysDeptMapper sysDeptMapper;

    private final ClassifyMapper classifyMapper;

    private final ISysNoticeService sysNoticeService;

    private final SysUserMapper sysUserMapper;

    private final ICommonService commonService;

    private final SysDeptMapper deptMapper;

    /**
     * 查询暂存登记
     *
     * @param id 暂存登记主键
     * @return 暂存登记
     */
    @Override
    public StagingVo queryById(String id) {
        //return baseMapper.selectVoById(id);
        return baseMapper.selectStagingVoByID(id);
    }

    @Override
    public StagingVo getStagingInfoByPno(String pno) {

        return baseMapper.getStagingInfoByPno(pno);
    }

    /**
     * 查询暂存登记列表
     *
     * @param bo 暂存登记
     * @return 暂存登记
     */
    @Override
    public TableDataInfo<StagingVo> queryPageList(StagingBo bo, PageQuery pageQuery) {
        //查询市级未登记的数据
        // LambdaQueryWrapper<Staging> lqw = buildQueryWrapper(bo);
        // Page<StagingVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        SysDept dept = deptMapper.selectById(LoginHelper.getDeptId());
        if (dept != null && StringUtils.isNotBlank(dept.getDeptCode())) {
            if (dept.getDeptCode().startsWith("3504")) {
                bo.setIsSecurity("1");
            }
        }
        Page<StagingVo> result = baseMapper.selectPageStagingList(pageQuery.build(), bo);
//        if(result != null && result.getRecords() != null && result.getRecords().size() > 0){
//            result.getRecords().forEach(item->{
//                SysOssBo ossBo = new SysOssBo();
//                ossBo.setBuss("property");
//                ossBo.setObjid(item.getPno());
//                item.setOss(sysOssMapper.selectSysOssList(ossBo));
//            });
//        }
        return TableDataInfo.build(result);
    }

    @Override
    public TableDataInfo<StagingInfoVo> getStagingPageList(StagingBo bo, PageQuery pageQuery) {

        List<String> officeIds = financeController.getUserDateScopes();
        if (officeIds != null && officeIds.size() != 0) {
            bo.setOfficeIds(officeIds);
        }
        Page<StagingInfoVo> result = baseMapper.getStagingPageList(pageQuery.build(), bo);
        return TableDataInfo.build(result);
    }

    /**
     * 查询暂存登记列表
     *
     * @param bo 暂存登记
     * @return 暂存登记
     */
    @Override
    public List<StagingVo> queryList(StagingBo bo) {
        // LambdaQueryWrapper<Staging> lqw = buildQueryWrapper(bo);
        // return baseMapper.selectVoList(lqw);
        return baseMapper.selectStagingList(bo);
    }

    private LambdaQueryWrapper<Staging> buildQueryWrapper(StagingBo bo) {

        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Staging> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getDeptId() != null, Staging::getDeptId, bo.getDeptId());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), Staging::getType, bo.getType());
        lqw.between(params.get("beginRegisterTime") != null && params.get("endRegisterTime") != null,
                Staging::getRegisterTime, params.get("beginRegisterTime"), params.get("endRegisterTime"));
        lqw.eq(StringUtils.isNotBlank(bo.getRegisterer()), Staging::getRegisterer, bo.getRegisterer());
        lqw.eq(StringUtils.isNotBlank(bo.getStoreId()), Staging::getStoreId, bo.getStoreId());
        lqw.eq(StringUtils.isNotBlank(bo.getRemark()), Staging::getRemark, bo.getRemark());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), Staging::getStatus, bo.getStatus());
        lqw.between(params.get("beginTransferTime") != null && params.get("endTransferTime") != null,
                Staging::getTransferTime, params.get("beginTransferTime"), params.get("endTransferTime"));
        lqw.eq(StringUtils.isNotBlank(bo.getTransferRemark()), Staging::getTransferRemark, bo.getTransferRemark());
        lqw.between(params.get("beginReturnTime") != null && params.get("endReturnTime") != null,
                Staging::getReturnTime, params.get("beginReturnTime"), params.get("endReturnTime"));
        lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
                Staging::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
        lqw.eq(StringUtils.isNotBlank(bo.getCreateBy()), Staging::getCreateBy, bo.getCreateBy());
        lqw.eq(StringUtils.isNotBlank(bo.getDelFlag()), Staging::getDelFlag, bo.getDelFlag());
        lqw.eq(StringUtils.isNotBlank(bo.getReturnStatus()), Staging::getReturnStatus, bo.getReturnStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getTransferStatus()), Staging::getTransferStatus, bo.getTransferStatus());
        lqw.eq(bo.getTransferDept() != null, Staging::getTransferDept, bo.getTransferDept());
        lqw.eq(StringUtils.isNotBlank(bo.getTransferStore()), Staging::getTransferStore, bo.getTransferStore());
        lqw.eq(StringUtils.isNotBlank(bo.getPno()), Staging::getPno, bo.getPno());
        lqw.eq(StringUtils.isNotBlank(bo.getCaseNo()), Staging::getCaseNo, bo.getCaseNo());
        lqw.like(StringUtils.isNotBlank(bo.getName()), Staging::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getClassifyId()), Staging::getClassifyId, bo.getClassifyId());
        lqw.eq(StringUtils.isNotBlank(bo.getSecondClassifyId()), Staging::getSecondClassifyId, bo.getSecondClassifyId());
        lqw.eq(StringUtils.isNotBlank(bo.getThirdClassifyId()), Staging::getThirdClassifyId, bo.getThirdClassifyId());
        lqw.eq(StringUtils.isNotBlank(bo.getFeature()), Staging::getFeature, bo.getFeature());
        lqw.eq(bo.getOfficeId() != null, Staging::getOfficeId, bo.getOfficeId());
        lqw.like(StringUtils.isNotBlank(bo.getTransferDeptName()), Staging::getTransferDeptName, bo.getTransferDeptName());
        lqw.eq(StringUtils.isNotBlank(bo.getUnit()), Staging::getUnit, bo.getUnit());
        lqw.eq(StringUtils.isNotBlank(bo.getCountyTransferStatus()), Staging::getCountyTransferStatus, bo.getCountyTransferStatus());
        return lqw;
    }

    /**
     * 新增暂存登记
     *
     * @param bo 暂存登记
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(StagingBo bo) {

        Staging add = BeanUtil.toBean(bo, Staging.class);
        validEntityBeforeSave(add);

        //填充UUID
        add.setId(IdUtil.simpleUUID());
        add.setDelFlag("0");
        add.setStatus("0");
        add.setTransferStatus("0");//默认设置所队移交状态为待登记
        add.setCountyTransferStatus("0");//默认设置区县移交状态为待登记

        //消息接收人
        List<String> toUsers = new ArrayList<>();
        String content = "";

//        Long type = 1l;//默认市级
        String transferStatus = "0";//所队状态
        String countyTransferStatus = "0";//区县状态
        String propertyStatus = "0";
        if (LoginHelper.checkLoginUser()) {
            if (LoginHelper.getLoginUser().getRolePermission().contains("sdcangguang")) {
//                type = 3l;
                transferStatus = "2";
            }
            if (LoginHelper.getLoginUser().getRolePermission().contains("qxcangguang")) {
//                type = 2l;
                transferStatus = "2";
                countyTransferStatus = "2";
                propertyStatus = "2";
            }
        }
        List<SysOss> osses = new ArrayList<>();
        //设置附件
        if (bo.getOss() != null && bo.getOss().size() > 0) {
            for (SysOss oss : bo.getOss()) {
                SysOss old = sysOssMapper.selectById(oss.getOssId());
                oss.setObjid(add.getId());
                oss.setBuss("staging");
                sysOssMapper.updateById(oss);

                //迁移附件，财物表
//                SysOss copyOss =  sysOssMapper.selectOne(new LambdaQueryWrapper<SysOss>().eq(SysOss::getBuss,"property").eq(SysOss::getObjid,add.getPno()));

//                if(copyOss == null){
//                    copyOss = new SysOss();
//                    BeanUtil.copyProperties(old,copyOss,"ossId");
//                    copyOss.setObjid(add.getPno());
//                    copyOss.setBuss("property");
//                }else {
//                    String[] ignore = new String[]{"ossId","","objid","buss"};
//                    BeanUtil.copyProperties(old,copyOss,ignore);
//                }

                SysOss copyOss = new SysOss();
                BeanUtil.copyProperties(old, copyOss, "ossId");
                copyOss.setObjid(add.getPno());
                copyOss.setBuss("property");
                sysOssMapper.insertOrUpdate(copyOss);
                osses.add(copyOss);
            }
        }

        /**
         * action: add.手动新增
         *
         * 新增财物信息
         * transferStatus 0.待登记 1.已登记
         *
         * 新增库存信息
         * status 0.在库 1.出库 2.调用 3.处置
         */

        Staging staging = baseMapper.selectOne(new LambdaQueryWrapper<Staging>().eq(Staging::getPno, add.getPno()));
        if (staging == null) {
            //判断是手动新增还是下发新增
            if (StringUtils.isNotEmpty(bo.getAction()) && bo.getAction().equals("add")) {
                /**
                 * 部分登记
                 * status 0.待登记 1.部分登记 2.已登记
                 */
//                if(add.getNums() - add.getReceiveNums() > 0){
                add.setTransferStatus("2");
                add.setNums(bo.getReceiveNums());
//                }
//                if(add.getNums() - add.getReceiveNums() == 0){
//                    add.setTransferStatus("2");
//                }
//                add.setTransferStatus(transferStatus);//设置所队移交状态
//                add.setCountyTransferStatus(countyTransferStatus);//设置区县移交状态
            }

        } else {
            add.setId(staging.getId());
            add.setTransferStatus(staging.getTransferStatus());
            add.setStatus(staging.getStatus());
            add.setCountyTransferStatus(staging.getCountyTransferStatus());
        }
        boolean flag = baseMapper.insertOrUpdate(add);


        //判断是手动新增还是下发新增
        if (flag && StringUtils.isNotEmpty(bo.getAction()) && bo.getAction().equals("add")) {
            //新增财物信息
            Property property = propertyMapper.selectOne(new LambdaQueryWrapper<Property>().eq(Property::getPno, add.getPno()));

            if (property == null) {
                property = new Property();
                String[] ignoreProperties = {"id", "createBy", "createTime", "updateBy", "updateTime"};
                BeanUtil.copyProperties(add, property, ignoreProperties);
                property.setId(IdUtil.simpleUUID());
                property.setDelFlag("0");
                property.setStatus("0");
                property.setNums(add.getReceiveNums());
                property.setInnums(add.getReceiveNums());
                property.setOutnums(0L);
                property.setDeals(0L);
                property.setTnums(0L);
                property.setRnums(0L);
                property.setBelongDeptName(add.getTransferDeptName());//所属单位（公安，检察院，法院）

                //财物日志
                content = "接收登记：{物品编号：" + property.getPno()
                        + "，物品名称：" + property.getName()
                        + (StringUtils.isNotEmpty(add.getRemark()) ? ("，说明：" + add.getRemark()) : "") + "}"
                        + (StringUtils.isNotEmpty(add.getTransferRemark()) ? ("，调用说明：" + add.getTransferRemark()) : "") + "}";
                content = "接收登记";
                Long type = 1L;
                if (LoginHelper.checkLoginUser()) {
                    SysDept dept = sysDeptMapper.selectById(LoginHelper.getDeptId());
                    type = dept.getLevel();
                }
                addPropertyLog(add, content, PropertyLogNode.getNodeCodeByBuss(type, "0"), bo.getSource(), osses);

                property.setTransferStatus(propertyStatus);//设置所队移交状态
                property.setCountyTransferStatus("0");//设置区县移交状态
                property.setTransferType(add.getType());//设置移交类型
            } else {
                BeanUtil.copyProperties(add, property, "id");
                property.setNums(add.getReceiveNums());
                property.setInnums(add.getReceiveNums());
                property.setBelongDeptName(add.getTransferDeptName());//所属单位（公安，检察院，法院）
                //财物日志
                content = "更新接收登记：{物品编号：" + property.getPno()
                        + "，物品名称：" + property.getName()
                        + (StringUtils.isNotEmpty(add.getRemark()) ? ("，说明：" + add.getRemark()) : "") + "}"
                        + (StringUtils.isNotEmpty(add.getTransferRemark()) ? ("，调用说明：" + add.getTransferRemark()) : "") + "}";
                content = "更新接收登记";
                addPropertyLog(add, content, PropertyLogNode.getNodeCodeByBuss(1L, "0"), bo.getSource(), osses);
            }

            property.setCharacter(add.getFeature());//设置物品特征
            property.setBelongDeptId(add.getTransferDept());//设置保管单位
            property.setBelongDeptName(add.getTransferDeptName());////所属单位（公安，检察院，法院）
            property.setPersonName(add.getRegisterer());//设置办案民警
//            property.setBelongStoreId(add.getStoreId());//设置保管仓库
            property.setTransferType(add.getType());//设置移交类型
            propertyMapper.insertOrUpdate(property);

            //数据推送
            add.setRegisterer(LoginHelper.getNickname());
            pushDatas(add, property, osses);
        } else {//接收到新的财物 下发单位仓管员通知
            if (toUsers != null && toUsers.size() > 0) {
                PushContent pushContent = new PushContent();
                pushContent.setTitle("接收财物提醒");
                pushContent.setPayload("{\"page\":\"/pagesOMS/staging/index\"}");
                pushContent.setClickType("payload");
                String contentInfo = "您有" + (bo.getNums() != null ? bo.getNums() : "1") + (StringUtils.isNotBlank(bo.getUnit()) ? bo.getUnit() : "件") + " " + bo.getName() + "待接收登记，请及时处理！";
                pushContent.setContent(contentInfo);
                pushContent.setBody(pushContent.getContent());
                sysNoticeService.sendNotice("3", toUsers, add.getDeptId(), pushContent, contentInfo);
            }
        }

        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean inserStagingByBo(StagingBo bo) {

        Staging add = BeanUtil.toBean(bo, Staging.class);
        validEntityBeforeSave(add);

        if (StringUtils.isBlank(add.getPno())) {
            throw new ServiceException("物品编号不能为空");
        }
        StagingVo old = baseMapper.getVoByPno(add.getPno());
        if (old != null) {
            throw new ServiceException("物品编号重复，请重新输入");
        }

        //消息接收人
        List<String> toUsers = new ArrayList<>();


        /**
         * 默认配置
         */
        add.setId(IdUtil.simpleUUID());
        add.setStatus("0");
        add.setDelFlag("0");

        /**
         * 新增默认已登记
         */
        add.setTransferStatus("2");
        add.setNums(bo.getReceiveNums());

        //暂缓/调用天数计算
        if ((add.getType().equals("2") || add.getType().equals("1")) && add.getStorageDays() != null) {
            String today = DateUtils.date2String(new Date(), "yyyy-MM-dd") + " 23:59:59";
            add.setStorageDaysTime(DateUtils.addDays(DateUtils.string2Date(today), add.getStorageDays()));
        }


        /**
         * 附件
         */
        List<SysOss> ossList = new ArrayList<>();
        if (bo.getOss() != null && bo.getOss().size() > 0) {
            String[] ignoreProperties = {"ossId", "createBy", "createTime", "updateBy", "updateTime"};
            bo.getOss().stream().forEach(oss -> {
                oss.setBuss("staging");
                oss.setObjid(add.getId());
                sysOssMapper.updateById(oss);


                SysOss copyOss = new SysOss();
                BeanUtil.copyProperties(oss, copyOss, ignoreProperties);
                copyOss.setBuss("property");
                copyOss.setObjid(add.getPno());
                sysOssMapper.insert(copyOss);
                ossList.add(copyOss);
            });
        }
        boolean flag = baseMapper.insert(add) > 0;

        if (flag) {
            /**
             * 已登记的物品，自动生成一条物品property信息
             */
            Property enty = new Property();
            String[] ignoreProperties = {"id", "createBy", "createTime", "updateBy", "updateTime"};
            BeanUtil.copyProperties(add, enty, ignoreProperties);

            /**
             * 默认配置
             */
            enty.setId(IdUtil.simpleUUID());
            enty.setDelFlag("0");
            enty.setStatus("0");

            /**
             * nums 库存
             * innums 入库数
             * outnums 出库数
             * deals 处置数
             * tnums 调用数
             * rnums 归还数
             */
            enty.setNums(add.getReceiveNums());
            enty.setInnums(add.getReceiveNums());
            enty.setOutnums(0L);
            enty.setDeals(0L);
            enty.setTnums(0L);
            enty.setRnums(0L);

            enty.setCharacter(add.getFeature());//设置物品特征
            enty.setBelongDeptId(add.getTransferDept());//设置保管单位
            enty.setBelongDeptName(add.getTransferDeptName());////所属单位（公安，检察院，法院）
            enty.setPersonName(add.getRegisterer());//设置办案民警
            enty.setTransferType(add.getType());//设置移交类型
            enty.setTransferStatus("0");

            propertyMapper.insert(enty);

            //数据推送
            add.setRegisterer(LoginHelper.getNickname());
            pushDatas(add, enty, ossList);

            String info = JsonUtils.toJsonString(enty);
            commonService.savePropertyLogByOperator(enty.getPno(), enty.getId(), enty.getName(),
                    PropertyLogType.STAGING.getCode(), "接收登记", enty.getOfficeId(), info, null, enty.getNums(), ossList, "数据同步");

            if (toUsers != null && toUsers.size() > 0) {
                String contentInfo = "您有" + (bo.getNums() != null ? bo.getNums() : "1") + (StringUtils.isNotBlank(bo.getUnit()) ? bo.getUnit() : "件") + " " + bo.getName() + "待接收登记，请及时处理！";
                commonService.sendSysNotice("3", toUsers, add.getDeptId(), "接收物品提醒", contentInfo, "{\"page\":\"/pagesOMS/staging/index\"}");
            }

            //修改PB表登记类型
            Date pbDate = new Date();
            propertyMapper.updatePBRegisterTypeByNo(add.getPno(), add.getType(), pbDate.getTime());

        }

        return flag;
    }

    /**
     * 数据接收
     *
     * @param bo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertApiByBo(StagingBo bo) {

        boolean flag = false;
        Staging add = BeanUtil.toBean(bo, Staging.class);
        validEntityBeforeSave(add);

        //消息接收人
        List<String> toUsers = new ArrayList<>();

        //查询是否已存在当前编号的接收登记
        StagingVo oldVo = baseMapper.getVoByPno(bo.getPno());
        if (oldVo == null) {
            /**
             * 默认配置
             */
            add.setId(IdUtil.simpleUUID());
            add.setDelFlag("0");
            add.setStatus("0");

            add.setTransferStatus("0");//移交登记状态
            add.setCountyTransferStatus("0");
            flag = baseMapper.insertOrUpdate(add);
        } else {
            if (oldVo.getTransferStatus().equals("2")) {
                Staging update = BeanUtil.toBean(oldVo, Staging.class);
                update.setOfficeId(add.getOfficeId());
                update.setDeptId(add.getDeptId());
                update.setRegisterer(add.getRegisterer());
                update.setTransferDeptName(add.getTransferDeptName());
                update.setCustodianPlace(add.getCustodianPlace());
                update.setWarehouseLocation(add.getWarehouseLocation());
                flag = baseMapper.insertOrUpdate(update);
            } else {
                add.setId(oldVo.getId());
                add.setStatus(oldVo.getStatus());
                add.setTransferStatus(oldVo.getTransferStatus());
                add.setCountyTransferStatus(oldVo.getCountyTransferStatus());
                add.setReceiveNums(oldVo.getReceiveNums());//接收数量
                flag = baseMapper.insertOrUpdate(add);
            }
//            update.setOfficeId(add.getOfficeId());
//            update.setDeptId(add.getDeptId());
//            update.setRegisterer(add.getRegisterer());
//            update.setTransferDeptName(add.getTransferDeptName());
//            flag = baseMapper.insertOrUpdate(update);
//            add.setId(oldVo.getId());
//            add.setStatus(oldVo.getStatus());
//            add.setTransferStatus(oldVo.getTransferStatus());
//            add.setCountyTransferStatus(oldVo.getCountyTransferStatus());
//            add.setReceiveNums(oldVo.getReceiveNums());//接收数量
        }

        /**
         * 如果是已登记物品，同步更新物品信息
         */
        Property property = propertyMapper.selectPropertyByPno(add.getPno());
        if (property != null) {
            property.setDeptId(add.getDeptId());
            property.setPersonName(add.getRegisterer());
            property.setOfficeId(add.getOfficeId());
//            String[] ignoreProperties = {"id","createBy","createTime","updateBy","updateTime"};
//            BeanUtil.copyProperties(add,property,ignoreProperties);
//            property.setNums(add.getReceiveNums());
//            property.setInnums(add.getReceiveNums());
            property.setBelongDeptName(add.getTransferDeptName());//所属单位（公安，检察院，法院）
//            property.setCharacter(add.getFeature());//设置物品特征
            property.setBelongDeptId(add.getTransferDept());//设置保管单位
            property.setWarehouseLocation(add.getWarehouseLocation());
            property.setCustodianPlace(add.getCustodianPlace());
//            property.setPersonName(add.getRegisterer());//设置办案民警
//            property.setTransferType(add.getType());//设置移交类型
            propertyMapper.updateById(property);

            //数据推送
//            add.setRegisterer(LoginHelper.getNickname());

            pushDatas(add, property, null);

//            String info = JsonUtils.toJsonString(property);
//            commonService.savePropertyLogByOperator(property.getPno(),property.getId(),property.getName(),
//                PropertyLogType.STAGING.getCode(),"更新接收登记",property.getOfficeId(),info,null,property.getNums(),null,"数据同步");
        }


        if (toUsers != null && toUsers.size() > 0) {
            String contentInfo = "您有" + (bo.getNums() != null ? bo.getNums() : "1") + (StringUtils.isNotBlank(bo.getUnit()) ? bo.getUnit() : "件") + " " + bo.getName() + "待接收登记，请及时处理！";
            commonService.sendSysNotice("3", toUsers, add.getDeptId(), "接收物品提醒", contentInfo, "{\"page\":\"/pagesOMS/staging/index\"}");
        }

        return flag;
    }

    public void pushDatas(Staging enty, Property property, List<SysOss> oss) {

        StagingDatasVo data = new StagingDatasVo();
        BeanUtil.copyProperties(property, data);
        data.setWpbh(property.getPno());
        data.setProname(property.getName());

        if (property.getDeptId() != null) {
            SysDept dept = sysDeptMapper.selectById(enty.getDeptId());
            data.setDeptNo(dept.getDeptCode());
            data.setDeptName(dept.getDeptName());
            data.setUndertaker(dept.getDeptCode());
        }

        if (property.getBelongDeptId() != null) {
            SysDept dept = sysDeptMapper.selectById(property.getBelongDeptId());
            data.setBelongofficeid(dept.getDeptCode());
        }

        if (property.getOfficeId() != null) {
            SysDept dept = sysDeptMapper.selectById(property.getOfficeId());
            data.setOfficeid(dept.getDeptCode());
        }
        if (enty.getStoreId() != null) {
            Store store = storeMapper.selectById(enty.getStoreId());
            data.setCustodianplace(store.getName());
        } else {
            data.setCustodianplace(property.getCustodianPlace());
        }
        data.setPronum(enty.getNums());
        data.setReceiveNums(enty.getReceiveNums());
        data.setUnit(enty.getUnit());

        if (!StringUtils.isEmpty(property.getClassifyId())) {
            Classify classify = classifyMapper.selectById(property.getClassifyId());
            data.setProcategory(classify.getClassifyNo());
        }

        if (!StringUtils.isEmpty(property.getSecondClassifyId())) {
            Classify classify = classifyMapper.selectById(property.getSecondClassifyId());
            data.setSeccategory(classify.getClassifyNo());
        }

        if (!StringUtils.isEmpty(property.getThirdClassifyId())) {
            Classify classify = classifyMapper.selectById(property.getThirdClassifyId());
            data.setThirdcategory(classify.getClassifyNo());
        }

        data.setWarehouselocation(property.getWarehouseLocation());

        data.setType(enty.getType());
        data.setRegisterTime(enty.getRegisterTime());
        data.setRemark(enty.getRemark());
        data.setRegisterer(enty.getRegisterer() == null ? "" : enty.getRegisterer());
        data.setFeature(enty.getFeature());
        data.setCreatedate(enty.getCreateTime());
        data.setUpdatedate(enty.getUpdateTime());
        data.setPersonname(enty.getRegisterer() == null ? "" : enty.getRegisterer());
        data.setOss(oss);
        data.setDelflag(enty.getDelFlag() != null ? Integer.valueOf(enty.getDelFlag()) : 0);
        PropertyLogBo logBo = new PropertyLogBo();
        logBo.setPno(enty.getPno());
        data.setLogs(propertyLogMapper.selectPropertyLogList(logBo));
        PushDatasUtil.pushStagingDatas(data);
    }

    /**
     * 修改暂存登记
     *
     * @param bo 暂存登记
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(StagingBo bo) {

        Staging update = BeanUtil.toBean(bo, Staging.class);
        validEntityBeforeSave(update);

        SysDept dept = sysDeptMapper.selectById(LoginHelper.getDeptId());

//        Integer type = 1l;//默认市级
//        if(LoginHelper.getLoginUser().getRolePermission().contains("sdcangguang")){
//            type = 3;
//        }
//        if(LoginHelper.getLoginUser().getRolePermission().contains("qxcangguang")){
//            type = 2;
//        }

        List<SysOss> osses = new ArrayList<>();

        /**
         * 部分登记
         * status 0.待登记 1.部分登记 2.已登记
         */
        update.setNums(update.getReceiveNums());
        update.setTransferStatus("2");//设置移交状态
        //设置附件
        if (bo.getOss() != null && bo.getOss().size() > 0) {
            for (SysOss oss : bo.getOss()) {
                SysOss old = sysOssMapper.selectById(oss.getOssId());
                oss.setObjid(update.getId());
                oss.setBuss("staging");
                sysOssMapper.updateById(oss);

                //迁移附件，财物表
//                SysOss copyOss =  sysOssMapper.selectOne(new LambdaQueryWrapper<SysOss>().eq(SysOss::getBuss,"property").eq(SysOss::getObjid,update.getPno()));

//                if(copyOss == null){
//                    copyOss = new SysOss();
//                    BeanUtil.copyProperties(old,copyOss,"ossId");
//                    copyOss.setObjid(update.getPno());
//                    copyOss.setBuss("property");
//                }else {
//                    String[] ignore = new String[]{"ossId","","objid","buss"};
//                    BeanUtil.copyProperties(old,copyOss,ignore);
//                }

                SysOss copyOss = new SysOss();
                BeanUtil.copyProperties(old, copyOss, "ossId");
                copyOss.setObjid(update.getPno());
                copyOss.setBuss("property");
                sysOssMapper.insertOrUpdate(copyOss);
                osses.add(copyOss);
            }
        }

        //新增财物信息
        Property property = propertyMapper.selectOne(new LambdaQueryWrapper<Property>().eq(Property::getPno, update.getPno()));
        String[] ignoreProperties = {"id", "createBy", "createTime", "updateBy", "updateTime"};
        if (property == null) {
            property = new Property();
            BeanUtil.copyProperties(update, property, ignoreProperties);
            property.setId(IdUtil.simpleUUID());
            property.setDelFlag("0");
            property.setStatus("0");
            property.setNums(update.getReceiveNums());
            property.setInnums(update.getReceiveNums());
            property.setOutnums(0L);
            property.setDeals(0L);
            property.setTnums(0L);
            property.setRnums(0L);

        } else {
            BeanUtil.copyProperties(update, property, ignoreProperties);
            property.setNums(update.getReceiveNums());
            property.setInnums(update.getReceiveNums());
        }
        property.setTransferStatus("0");//设置所队移交状态
        property.setCharacter(update.getFeature());//设置物品特征
        property.setBelongDeptId(LoginHelper.getDeptId());//设置保管单位
        property.setPersonName(update.getRegisterer());//设置办案民警
        property.setBelongStoreId(update.getStoreId());//设置保管仓库
        property.setTransferType(update.getType());//设置移交类型
        propertyMapper.insertOrUpdate(property);

        //财物日志
        String content = "接收登记：{物品编号：" + property.getPno()
                + "，物品名称：" + property.getName()
                + (StringUtils.isNotEmpty(update.getRemark()) ? ("，说明：" + update.getRemark()) : "") + "}"
                + (StringUtils.isNotEmpty(update.getTransferRemark()) ? ("，调用说明：" + update.getTransferRemark()) : "") + "}";
        content = "接收登记";
        addPropertyLog(update, content, PropertyLogNode.getNodeCodeByBuss(dept.getLevel(), "0"), bo.getSource(), osses);

        int flag = baseMapper.updateById(update);
        update.setRegisterer(LoginHelper.getNickname());
        pushDatas(update, property, osses);

        return flag > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateStagingByBo(StagingBo bo) {

        Staging update = BeanUtil.toBean(bo, Staging.class);
        validEntityBeforeSave(update);

        //消息接收人
        List<String> toUsers = new ArrayList<>();
        String content = "";

        update.setNums(update.getReceiveNums());
        update.setTransferStatus("2");//0-待登记 2-已登记

        List<SysOss> ossList = new ArrayList<>();
        //设置附件
        if (bo.getOss() != null && bo.getOss().size() > 0) {
            /**
             * 重新生成物品图片
             */
            SysOssBo ossBo = new SysOssBo();
            ossBo.setBuss("property");
            ossBo.setObjid(update.getPno());
            List<SysOss> propertyOss = sysOssMapper.selectSysOssList(ossBo);

            if (propertyOss != null && propertyOss.size() > 0) {
                propertyOss.stream().forEach(oss -> {
                    sysOssMapper.deleteById(oss);
                });
            }

            String[] ignoreProperties = {"ossId", "createBy", "createTime", "updateBy", "updateTime"};
            bo.getOss().stream().forEach(oss -> {
                oss.setBuss("staging");
                oss.setObjid(update.getId());
                sysOssMapper.updateById(oss);

                SysOss copyOss = new SysOss();
                BeanUtil.copyProperties(oss, copyOss, ignoreProperties);
                copyOss.setBuss("property");
                copyOss.setObjid(update.getPno());
                sysOssMapper.insert(copyOss);
                ossList.add(copyOss);
            });
        }

        //暂缓/调用天数计算
        if ((update.getType().equals("2") || update.getType().equals("1")) && update.getStorageDays() != null) {
            String today = DateUtils.date2String(new Date(), "yyyy-MM-dd") + " 23:59:59";
            update.setStorageDaysTime(DateUtils.addDays(DateUtils.string2Date(today), update.getStorageDays()));
        }

        boolean flag = baseMapper.updateById(update) > 0;

        if (flag) {
            /**
             * 如何是已登记物品，同步更新物品信息
             */
            Property property = propertyMapper.selectPropertyByPno(update.getPno());
            if (property != null) {
                String[] ignoreProperties = {"id", "createBy", "createTime", "updateBy", "updateTime", "transferStatus"};
                BeanUtil.copyProperties(update, property, ignoreProperties);
                property.setNums(update.getReceiveNums());
                property.setInnums(update.getReceiveNums());
                property.setBelongDeptName(update.getTransferDeptName());//所属单位（公安，检察院，法院）
                property.setCharacter(update.getFeature());//设置物品特征
                property.setBelongDeptId(LoginHelper.getDeptId());//设置保管单位
                property.setPersonName(update.getRegisterer());//设置办案民警
                property.setTransferType(update.getType());//设置移交类型
                property.setCustodianPlace(update.getCustodianPlace());
                property.setWarehouseLocation(update.getWarehouseLocation());
                propertyMapper.updateById(property);
                content = "更新接收登记";
            } else {
                String[] ignoreProperties = {"id", "createBy", "createTime", "updateBy", "updateTime"};
                property = new Property();
                BeanUtil.copyProperties(update, property, ignoreProperties);

                /**
                 * 默认配置
                 */
                property.setId(IdUtil.simpleUUID());
                property.setDelFlag("0");
                property.setStatus("0");

                /**
                 * nums 库存
                 * innums 入库数
                 * outnums 出库数
                 * deals 处置数
                 * tnums 调用数
                 * rnums 归还数
                 */
                property.setNums(update.getReceiveNums());
                property.setInnums(update.getReceiveNums());
                property.setOutnums(0L);
                property.setDeals(0L);
                property.setTnums(0L);
                property.setRnums(0L);

                property.setCharacter(update.getFeature());//设置物品特征
                property.setBelongDeptId(LoginHelper.getDeptId());//设置保管单位
                property.setBelongDeptName(update.getTransferDeptName());////所属单位（公安，检察院，法院）
                property.setPersonName(update.getRegisterer());//设置办案民警
                property.setTransferType(update.getType());//设置移交类型
                property.setTransferStatus("0");
                property.setCustodianPlace(update.getCustodianPlace());
                property.setWarehouseLocation(update.getWarehouseLocation());

                propertyMapper.insert(property);
                content = "接收登记";
            }
            //数据推送
            update.setRegisterer(LoginHelper.getNickname());
            pushDatas(update, property, ossList);

            String info = JsonUtils.toJsonString(property);
            commonService.savePropertyLogByOperator(property.getPno(), property.getId(), property.getName(),
                    PropertyLogType.STAGING.getCode(), content, property.getOfficeId(), info, null, property.getNums(), ossList, "数据同步");


            if (toUsers != null && toUsers.size() > 0) {
                String contentInfo = "您有" + (bo.getNums() != null ? bo.getNums() : "1") + (StringUtils.isNotBlank(bo.getUnit()) ? bo.getUnit() : "件") + " " + bo.getName() + "待接收登记，请及时处理！";
                commonService.sendSysNotice("3", toUsers, update.getDeptId(), "接收物品提醒", contentInfo, "{\"page\":\"/pagesOMS/staging/index\"}");
            }

            //修改PB表登记类型
            Date pbDate = new Date();
            propertyMapper.updatePBRegisterTypeByNo(update.getPno(), update.getType(), pbDate.getTime());
        }


        return flag;
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(Staging entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除暂存登记
     *
     * @param ids 需要删除的暂存登记主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {

        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public Boolean deleteVoById(String id) {

        Staging staging = baseMapper.selectById(id);
        return commonService.StagingDelPush(staging);
    }

    //临时调用 - 调用单
    private void addTransfer(Staging staging) {

        ExWarehouse transfer = new ExWarehouse();
        transfer.setId(IdUtil.simpleUUID());
        transfer.setExno(getNo());
        transfer.setDeptId(staging.getDeptId());
        transfer.setStoreId(staging.getStoreId());
        transfer.setType("2");
        transfer.setReason(staging.getTransferRemark());
        transfer.setContacts(staging.getRegisterer());
        transfer.setReturnStatus("0");
        transfer.setNums(staging.getReceiveNums());
        transfer.setDelFlag("0");
        exWarehouseMapper.insert(transfer);

        ExWarehouseDtl dtl = new ExWarehouseDtl();
        BeanUtil.copyProperties(staging, dtl, "id");
        dtl.setId(IdUtil.simpleUUID());
        dtl.setWid(transfer.getId());
        dtl.setDelFlag("0");
        exWarehouseDtlMapper.insert(dtl);
    }

    //财物日志新增
    private void addPropertyLog(Staging staging, String content, String node, Integer source, List<SysOss> osses) {

        if (source == null || source == 1) {
            PropertyLog log = new PropertyLog();
            BeanUtil.copyProperties(staging, log, "id");
            log.setId(IdUtil.simpleUUID());
            log.setObjid(staging.getId());
            log.setLogTime(new Date());
            //            log.setOperator("数据同步");
            if (LoginHelper.checkLoginUser()) {
                log.setUserId(LoginHelper.getUserId());
                log.setOperator(LoginHelper.getNickname());
            } else {
                log.setOperator("数据同步");
            }

            log.setLogType(PropertyLogType.STAGING.getCode());//0-移交登记 1-入库 2-出库 3-调用 4-处置 5-交接 6-上架 7-挑拣
            log.setContent(content);
            log.setDelFlag("0");
            log.setNode(node);
            int i = propertyLogMapper.insert(log);
            if (osses != null && osses.size() > 0) {
                for (SysOss oss : osses) {
                    SysOss copyOss = new SysOss();
                    BeanUtil.copyProperties(oss, copyOss, "ossId");
                    copyOss.setObjid(log.getId());
                    copyOss.setBuss("propertyLog");
                    sysOssMapper.insert(copyOss);
                }
            }
            if (i > 0) {
                PropertyLogModelsVo data = new PropertyLogModelsVo();
                data.setApi("proBase");
                data.setData(propertyLogMapper.selectPropertyLogVoByID(log.getId()));
                PushDatasUtil.pushPropertyDatas(data);
            }
        }
    }


    /**
     * 库存日志新增
     * 0-接收登记 1-上架 2-挑拣 3-调用 4-处置
     */
    private void addInventoryLog(Inventory inventory, Long befores, Long nums, Long afters, String stagingId, String type) {

        InventoryLog log = new InventoryLog();
        log.setId(IdUtil.simpleUUID());
        log.setStockId(inventory.getId());
        log.setStoreId(inventory.getStoreId());
        log.setDeptId(inventory.getDeptId());
        log.setBefores(befores);
        log.setNums(nums);
        log.setAfters(afters);
        log.setType(type);
        log.setReferId(stagingId);
        if (LoginHelper.checkLoginUser()) {
            log.setOperator(LoginHelper.getUsername());
        } else {
            log.setOperator("--");
        }

        log.setStatus("0");
        log.setDelFlag("0");
        inventoryLogMapper.insert(log);
    }

    //编号
    public String getNo() {

        LambdaQueryWrapper<ExWarehouse> lqw = Wrappers.lambdaQuery();
        Long maxNumObject = exWarehouseMapper.selectCount(lqw);
        String num = "";
        String todayStr = DateUtils.date2String(new Date(), "yyMMdd");

        if (maxNumObject == null) {
            num = todayStr + "000001";
        } else {
            String maxnumStr = "00000" + maxNumObject.toString();
            String maxnumNo = maxnumStr.substring(maxnumStr.length() - 6, maxnumStr.length());
            String nextnumNo = StringUtils.nextNo(maxnumNo, 6);
            num = todayStr + nextnumNo;
        }
        return num;
    }

    @Override
    public List<StagingVo> getStaingByNo(String pno) {

        return baseMapper.selectVoList(new LambdaQueryWrapper<Staging>().eq(Staging::getPno, pno));
    }

    @Override
    public StagingVo getVoByNo(String pno) {

        return baseMapper.selectVoOne(new LambdaQueryWrapper<Staging>().eq(Staging::getPno, pno).eq(Staging::getTransferStatus, "2"));
    }

    @Override
    public List<Staging> listStaging(StagingBo bo) {

        LambdaQueryWrapper<Staging> lqw = buildQueryWrapper(bo);
        return baseMapper.selectList(lqw);
    }

    @Override
    public TableDataInfo<StagingVo> getNotCanterProList(String proNo, PageQuery pageQuery) {

        Page<StagingVo> notCanterProList = baseMapper.getNotCanterProList(pageQuery.build(), proNo);
        return TableDataInfo.build(notCanterProList);
    }

    @Override
    public TableDataInfo<StagingInfoVo> getXzProList(StagingBo bo, PageQuery pageQuery){
        List<String> officeIds = financeController.getUserDateScopes();
        if (officeIds != null && officeIds.size() != 0) {
            bo.setOfficeIds(officeIds);
        }
        Page<StagingInfoVo> result = baseMapper.getXzProList(pageQuery.build(), bo);
        return TableDataInfo.build(result);
    }
    @Override
    public String getXzPno(){
        String deptCode = sysDeptMapper.selectById(LoginHelper.getDeptId()).getDeptCode();
        String key = "pro_key_" + deptCode;

        String date = DateUtil.format(new Date(), "yyyyMM");
        if (!RedisUtils.hasKey(key)) {
            RedisUtils.setAtomicValue(key, 0);
            RedisUtils.expireThisMonth(key);
        }
        long orderNo = RedisUtils.incrAtomicValue(key);
        String generateNo = StrUtil.padPre(String.valueOf(orderNo), 6, "0");
        return "Z" + deptCode + date + generateNo;
    }

    @Override
    public StagingVo getXzProByPno(String pno){
        return baseMapper.getXzProByPno(pno);
    }
}
